package SGEngine

import (
	//"fmt"
	"github.com/gl"
)

type Sprite struct {
	Node
	mAtlas      *Atlas
	SpriteData  *AtlasSpriteData
	VBufferID   gl.Buffer
	TexBufferID gl.Buffer
	mProgram    *Program
	MColor      Color4
}

func (s *Sprite) GetAtlas() *Atlas {

	return s.mAtlas
}

func NewSprite(atlas *Atlas, name string) *Sprite {
	RSrpite := new(Sprite)
	RSrpite.MColor = NewColor4(1, 1, 1, 1)
	RSrpite.Node = DefaultNode()
	RSrpite.mAtlas = atlas
	RSrpite.NodeRender = RSrpite
	RSrpite.SpriteData = atlas.SpriteDatas[name]
	if RSrpite.SpriteData == nil {
		return nil
	}
	RSrpite.VBufferID = ACBufferMgr.GetVertexBuffer(BUFFER_Quad)
	RSrpite.mProgram = ACProgramMgr.GetProgram(PROGRAM_IMG)
	RSrpite.SetSprite(name)

	uniformTexture := RSrpite.mProgram.ProgramObject.GetUniformLocation("s_texture")
	RSrpite.MColor = NewColor4(1, 1, 1, 1)
	uniformTexture.Uniform1i(0)
	RSrpite.mProgram.ProgramObject.GetUniformLocation("inColor").Uniform4f(1, 1, 1, 1)

	return RSrpite
}

func (s *Sprite) SetSprite(name string) {

	if s.mAtlas.SpriteDatas[name].TexBuffer != 0 {
		s.SpriteData = s.mAtlas.SpriteDatas[name]
		s.TexBufferID = s.SpriteData.TexBuffer
		s.SpriteData.ReferenceCount++
		return
	}
	s.SpriteData = s.mAtlas.SpriteDatas[name]
	s.SpriteData.TexBuffer = s.GenSpriteTexBuffer()
	s.SpriteData.ReferenceCount = 1
	s.TexBufferID = s.SpriteData.TexBuffer
}

func (s *Sprite) GenSpriteTexBuffer() gl.Buffer {
	SizeXOne := float32(1.0) / float32(s.mAtlas.width)
	SizeYOne := float32(1.0) / float32(s.mAtlas.height)
	TexBuffer := make([]float32, 8)
	TexBuffer[0] = float32(s.SpriteData.Xpos) * SizeXOne
	TexBuffer[1] = float32(s.mAtlas.height-s.SpriteData.Ypos-s.SpriteData.Height) * SizeYOne

	TexBuffer[2] = float32(s.SpriteData.Xpos+s.SpriteData.Width) * SizeXOne
	TexBuffer[3] = float32(s.mAtlas.height-s.SpriteData.Ypos-s.SpriteData.Height) * SizeYOne

	TexBuffer[4] = float32(s.SpriteData.Xpos) * SizeXOne
	TexBuffer[5] = float32(s.mAtlas.height-s.SpriteData.Ypos) * SizeYOne

	TexBuffer[6] = float32(s.SpriteData.Xpos+s.SpriteData.Width) * SizeXOne
	TexBuffer[7] = float32(s.mAtlas.height-s.SpriteData.Ypos) * SizeYOne

	Rbuffer := gl.GenBuffer()
	Rbuffer.Bind(gl.ARRAY_BUFFER)
	gl.BufferData(gl.ARRAY_BUFFER, 8*4, TexBuffer, gl.STATIC_DRAW)
	return Rbuffer
}

func (s *Sprite) Render() {
	s.mAtlas.Tex.TexID.Bind(gl.TEXTURE_2D)
	s.mProgram.ProgramObject.Use()
	s.mProgram.ProgramObject.GetUniformLocation("inColor").Uniform4f(s.MColor.R, s.MColor.G, s.MColor.B, s.MColor.A)
	s.VBufferID.Bind(gl.ARRAY_BUFFER)
	s.mProgram.ProgramObject.GetAttribLocation("vPosition").AttribPointer(3, gl.FLOAT, false, 0, nil)
	s.mProgram.ProgramObject.GetAttribLocation("vPosition").EnableArray()
	s.TexBufferID.Bind(gl.ARRAY_BUFFER)
	s.mProgram.ProgramObject.GetAttribLocation("a_texCoord").AttribPointer(2, gl.FLOAT, false, 0, nil)
	s.mProgram.ProgramObject.GetAttribLocation("a_texCoord").EnableArray()
	gl.DrawArrays(gl.TRIANGLE_STRIP, 0, 4)
}

/////////////////////////////
